package com.peng.ormtest.step040.entity;


import com.mysql.jdbc.StringUtils;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class AbstractEntityHelperFactory {

    private static Map<Class<?>, AbstractEntityHelper> helperMap = new HashMap<>();

    public static AbstractEntityHelper getHelper(Class<?> clazz) throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        classPool.appendSystemPath();
        AbstractEntityHelper entityHelper = helperMap.get(clazz);
        if (Objects.nonNull(entityHelper)) {
            return entityHelper;
        }

        classPool.importPackage(ResultSet.class.getName());
        classPool.importPackage(clazz.getName());
        //获得AbstractEntityHelper类
        CtClass ctClass = classPool.getCtClass(AbstractEntityHelper.class.getName());
        //生成的类名称
        String makeClassName = clazz.getName() + "_$Helper";

        //构造一个继承AbstractEntityHelper类的类
        CtClass makeClass = classPool.makeClass(makeClassName, ctClass);

        //构造函数
        CtConstructor ctConstructor = new CtConstructor(new CtClass[0], makeClass);
        ctConstructor.setBody("{}");
        makeClass.addConstructor(ctConstructor);

        //通过反射和javasist 动态生成对对象ORM赋值操作
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("public   Object create(java.sql.ResultSet rs)throws Exception{\n");
        stringBuffer.append(clazz.getName())
                .append(" entity = new  ")
                .append(clazz.getName())
                .append("();\n");


        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            Column annotation = field.getAnnotation(Column.class);
            if (annotation == null) {
                continue;
            }
            String colName = annotation.name();
            if (StringUtils.isNullOrEmpty(colName)) {
                continue;
            }

            if (field.getType() == Long.TYPE) {
                stringBuffer.append("entity." + field.getName()).append(" =  rs.getInt(\"" + colName + "\");");
            } else if (field.getType().equals(String.class)) {
                stringBuffer.append("entity." + field.getName())
                        .append(" = rs.getString(\"" + colName + "\");\n");
            } else {
                System.out.println("暂不支持。。");
            }
        }


        stringBuffer.append("return entity;")
                .append("}");

        System.out.println(stringBuffer);

        CtMethod ctMethod = CtMethod.make(stringBuffer.toString(), makeClass);
        makeClass.addMethod(ctMethod);


//        makeClass.writeFile("E:\\jiagou\\herostory\\makeclass");

        Class aClass = makeClass.toClass();
        AbstractEntityHelper abstractEntityHelper = (AbstractEntityHelper) aClass.newInstance();
        helperMap.put(clazz, abstractEntityHelper);
        return abstractEntityHelper;
    }

    public static void main(String[] args) throws Exception {
        AbstractEntityHelper helper = new AbstractEntityHelperFactory().getHelper(UserEntity.class);
        System.out.println(helper);
    }

    public void A(ResultSet resultSet) {


    }
}
